/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.minetsh.imaging.view;

import me.minetsh.imaging.ResourceTable;
import me.minetsh.imaging.imageData.ImagePicker;
import me.minetsh.imaging.imageData.ResUtil;
import me.minetsh.imaging.photoview.ui.ImageCropAbility;
import me.minetsh.imaging.photoview.ui.ImageGridAbility;
import me.minetsh.imaging.view.stick.IMGStickerPortrait;
import me.minetsh.imaging.view.stick.IMGStickerView;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.media.image.PixelMap;
import ohos.utils.net.Uri;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * IMGEditBaseAbility
 *
 * @since 2021-07-27
 */
public class IMGEditBaseAbility extends Ability implements Component.ClickedListener, IMGStickerPortrait {
    private Text tv_cancel, tv_done;
    private String imgUri;
    private IMGView image;
    private Image rb_doodle, rb_mosaic;
    private Button btn_text, btn_clip, btn_undo, mosaic_undo;
    private RadioContainer layout_op_sub, rg_modes;
    private RadioButton rb_red, rb_black, rb_white, rb_green, rb_yellow, rb_blue;
    private StackLayout text_container;
    private TextField top_text;
    private DependentLayout mosaic_dl;
    private Map<RadioButton, AnimatorProperty> animatorPropertyMap = new HashMap<>();
    private List<IMGStickerView> stickerViews = new ArrayList<>();
    private StackLayout stick_container;
    private IMGMode mode;
    private Color selectTextColor = null;
    private Map<Color, RadioButton> colorButtonMap = new HashMap<>();
    private Color selectPaintColor = null;
    private Map<Color, RadioButton> colorPaintMap = new HashMap<>();
    private IMGMode preMode;

    @Override
    public void onStart(Intent data) {
        super.onStart(data);
        super.setUIContent(ResourceTable.Layout_ability_imgedit_base);
        int color = Color.getIntColor("#000000");
        getWindow().setStatusBarColor(color);

        image = (IMGView) findComponentById(ResourceTable.Id_image);
        if (data != null && data.getParams() != null) {
            imgUri = data.getStringParam(ImageGridAbility.EXTRAS_IMAGES);
            showPhoto(imgUri);
        }
        tv_cancel = (Text) findComponentById(ResourceTable.Id_tv_cancel);
        tv_done = (Text) findComponentById(ResourceTable.Id_tv_done);
        rb_doodle = (Image) findComponentById(ResourceTable.Id_rb_doodle);
        rb_mosaic = (Image) findComponentById(ResourceTable.Id_rb_mosaic);
        btn_text = (Button) findComponentById(ResourceTable.Id_btn_text);
        btn_clip = (Button) findComponentById(ResourceTable.Id_btn_clip);
        btn_undo = (Button) findComponentById(ResourceTable.Id_btn_undo);
        mosaic_undo = (Button) findComponentById(ResourceTable.Id_mosaic_undo);
        layout_op_sub = (RadioContainer) findComponentById(ResourceTable.Id_layout_op_sub);
        rb_red = (RadioButton) findComponentById(ResourceTable.Id_rb_red);
        rb_black = (RadioButton) findComponentById(ResourceTable.Id_rb_black);
        rb_white = (RadioButton) findComponentById(ResourceTable.Id_rb_white);
        rb_green = (RadioButton) findComponentById(ResourceTable.Id_rb_green);
        rb_yellow = (RadioButton) findComponentById(ResourceTable.Id_rb_yello);
        rb_blue = (RadioButton) findComponentById(ResourceTable.Id_rb_blue);
        rg_modes = (RadioContainer) findComponentById(ResourceTable.Id_rg_modes);
        text_container = (StackLayout) findComponentById(ResourceTable.Id_text_container);
        top_text = (TextField) findComponentById(ResourceTable.Id_top_text);
        mosaic_dl = (DependentLayout) findComponentById(ResourceTable.Id_mosaic_dl);
        stick_container = (StackLayout) findComponentById(ResourceTable.Id_stick_container);

        rb_red.setClickedListener(this);
        rb_black.setClickedListener(this);
        rb_white.setClickedListener(this);
        rb_green.setClickedListener(this);
        rb_yellow.setClickedListener(this);
        rb_blue.setClickedListener(this);
        animatorPropertyMap.put(rb_red, rb_red.createAnimatorProperty());
        animatorPropertyMap.put(rb_black, rb_black.createAnimatorProperty());
        animatorPropertyMap.put(rb_white, rb_white.createAnimatorProperty());
        animatorPropertyMap.put(rb_green, rb_green.createAnimatorProperty());
        animatorPropertyMap.put(rb_yellow, rb_yellow.createAnimatorProperty());
        animatorPropertyMap.put(rb_blue, rb_blue.createAnimatorProperty());

        tv_cancel.setClickedListener(this);
        tv_done.setClickedListener(this);
        rb_doodle.setClickedListener(this);
        rb_mosaic.setClickedListener(this);
        btn_text.setClickedListener(this);
        btn_clip.setClickedListener(this);
        btn_undo.setClickedListener(this);
        mosaic_undo.setClickedListener(this);
        stick_container.setClickedListener(this);

        image.setCanTouch(false);
    }

    @Override
    public void onClick(Component component) {
        if (component.getId() == ResourceTable.Id_tv_cancel) {
            if (mode == IMGMode.TEXT) {
                goPreState();
            } else {
                terminateAbility();
            }
        }
        if (component.getId() == ResourceTable.Id_tv_done) {
            if (mode == IMGMode.TEXT) {
                addTextStick();
                goPreState();
            } else {
                mode = IMGMode.NONE;
                drawText();
            }
        }
        if (component.getId() == ResourceTable.Id_rb_doodle) {
            //涂鸦
            choiceDoodleModel();
        }
        if (component.getId() == ResourceTable.Id_btn_text) {
            //文字
            choiceTextModel();
        }
        if (component.getId() == ResourceTable.Id_rb_mosaic) {
            //马赛克
            choiceMosaicModel();
        }
        if (component.getId() == ResourceTable.Id_btn_clip) {
            //裁剪
            choiceCropModel();
        }
        if (component.getId() == ResourceTable.Id_rb_red) {
            scaleReset();
            scaleLarge(rb_red);
            saveColorSelector(rb_red, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_red));
        }
        if (component.getId() == ResourceTable.Id_rb_black) {
            scaleReset();
            scaleLarge(rb_black);
            saveColorSelector(rb_black, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_black));
        }
        if (component.getId() == ResourceTable.Id_rb_white) {
            scaleReset();
            scaleLarge(rb_white);
            saveColorSelector(rb_white, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_white));
        }
        if (component.getId() == ResourceTable.Id_rb_green) {
            scaleReset();
            scaleLarge(rb_green);
            saveColorSelector(rb_green, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_cyan));
        }
        if (component.getId() == ResourceTable.Id_rb_yello) {
            scaleReset();
            scaleLarge(rb_yellow);
            saveColorSelector(rb_yellow, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_yellow));
        }
        if (component.getId() == ResourceTable.Id_rb_blue) {
            scaleReset();
            scaleLarge(rb_blue);
            saveColorSelector(rb_blue, ResUtil.getNewColor(getContext(), ResourceTable.Color_image_color_blue));
        }
        if (component.getId() == ResourceTable.Id_btn_undo) {
            image.undoDoodle();
        }
        if (component.getId() == ResourceTable.Id_mosaic_undo) {
            image.undoMosaic();
        }
        if (component.getId() == ResourceTable.Id_stick_container) {
            removeAllBorder();
        }
    }

    private void saveColorSelector(RadioButton radioButton, Color selectColor) {
        if (mode == IMGMode.TEXT) {
            selectTextColor = selectColor;
            top_text.setTextColor(selectTextColor);
            colorButtonMap.put(selectTextColor, radioButton);
        } else if (mode == IMGMode.DOODLE) {
            selectPaintColor = selectColor;
            image.setPaintColor(selectPaintColor);
            colorPaintMap.put(selectPaintColor, radioButton);
        }
    }

    private void finishByResult() {
        PixelMap pixelMap = image.getCurrentBitmap();
        GlobalData.getInstance().setResultPixelMap(pixelMap);
        Intent intent = new Intent();
        intent.setParam("resultImg", imgUri);
        setResult(101, intent);
        terminateAbility();
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);
        if (resultCode == ImagePicker.REQUEST_CODE_CROP && resultData != null) {
            GlobalData.getInstance().setResultPixelMap(GlobalData.getInstance().getCropperPixelMap());
            image.setPixelMap(GlobalData.getInstance().getCropperPixelMap());
        }
    }

    private void showPhoto(String strUri) {
        image.setPixelMap(PhotoUtil.getPixelMapByUri(getContext(), strUri));
    }

    private void scaleLarge(RadioButton rb) {
        AnimatorProperty animatorProperty = animatorPropertyMap.get(rb);
        animatorProperty.scaleX(1.25f).scaleY(1.25f).setDuration(100).start();
    }

    private void scaleReset() {
        for (Map.Entry<RadioButton, AnimatorProperty> entry : animatorPropertyMap.entrySet()) {
            entry.getValue().reset();
        }
    }

    private void showPaintColor() {
        layout_op_sub.setVisibility(Component.VISIBLE);
        btn_undo.setVisibility(Component.VISIBLE);
    }

    private void disMissPaintColor() {
        layout_op_sub.setVisibility(Component.INVISIBLE);
    }

    private void setIMGMode() {
        removeAllBorder();
        image.setIMGMode(mode);
    }

    private void setIMGModeNone() {
        if (mode == IMGMode.DOODLE) {
            mode = IMGMode.NONE;
            image.setCanTouch(false);
            disMissPaintColor();
            rb_doodle.setPixelMap(ResourceTable.Media_image_ic_doodle);
        }
        if (mode == IMGMode.MOSAIC) {
            mode = IMGMode.NONE;
            image.setCanTouch(false);
            hideMosaicTip();
            rb_mosaic.setPixelMap(ResourceTable.Media_image_ic_mosaic);
        }
    }

    private void resetButtonState() {
        rb_doodle.setPixelMap(ResourceTable.Media_image_ic_doodle);
        rb_mosaic.setPixelMap(ResourceTable.Media_image_ic_mosaic);
    }

    private void drawText() {
        removeAllBorder();
        image.drawText(stickerViews, new IMGView.IMGCallBack() {
            @Override
            public void drawComplete(boolean isComplete) {
                finishByResult();
            }
        });
        stick_container.removeAllComponents();
    }

    private void addTextStick() {
        if (top_text.getText().isEmpty()) {
            return;
        }

        removeAllBorder();
        IMGStickerView imgStickerView = new IMGStickerView(getContext());
        ComponentContainer.LayoutConfig config =
                new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT,
                        ComponentContainer.LayoutConfig.MATCH_CONTENT);
        config.setMarginTop(stick_container.getHeight() / 2 - top_text.getHeight() / 2);
        config.setMarginLeft(stick_container.getWidth() / 2 - top_text.getWidth() / 2);
        imgStickerView.setLayoutConfig(config);
        imgStickerView.setStickerText(top_text.getText(), top_text.getTextColor());
        imgStickerView.setIMGStickerPortrait(this);
        imgStickerView.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                removeAllBorder();
                imgStickerView.setCanTouch(true);
                imgStickerView.showBorder();
            }
        });
        stick_container.addComponent(imgStickerView);
        stickerViews.add(imgStickerView);
    }

    private void removeAllBorder() {
        for (IMGStickerView imgStickerView : stickerViews) {
            imgStickerView.setCanTouch(false);
            imgStickerView.disMissBorder();
        }
    }

    @Override
    public void remove(IMGStickerView stickerView) {
        stick_container.removeComponent(stickerView);
        stickerViews.remove(stickerView);
    }

    private void showMosaicTip() {
        mosaic_dl.setVisibility(Component.VISIBLE);
    }

    private void hideMosaicTip() {
        mosaic_dl.setVisibility(Component.INVISIBLE);
    }

    /**
     * 涂鸦模式
     */
    private void choiceDoodleModel() {
        resetButtonState();
        if (mode == IMGMode.DOODLE) {
            setIMGModeNone();
        } else {
            mode = IMGMode.DOODLE;
            rb_doodle.setPixelMap(ResourceTable.Media_image_ic_doodle_checked);
            setIMGMode();
            showPaintColor();
            hideMosaicTip();
            image.setCanTouch(true);
            if (selectPaintColor == null) {
                rb_red.callOnClick();
            } else {
                colorPaintMap.get(selectPaintColor).callOnClick();
            }
        }
    }

    /**
     * 文字贴片模式
     */
    private void choiceTextModel() {
        if (mode == null) {
            mode = IMGMode.TEXT;
        }
        preMode = mode;
        mode = IMGMode.TEXT;
        setIMGMode();
        hideMosaicTip();
        showPaintColor();
        image.setCanTouch(false);
        rg_modes.setVisibility(Component.INVISIBLE);
        text_container.setVisibility(Component.VISIBLE);
        top_text.requestFocus();
        btn_undo.setVisibility(Component.INVISIBLE);
        if (selectTextColor == null) {
            rb_white.callOnClick();
        } else {
            colorButtonMap.get(selectTextColor).callOnClick();
        }
    }

    /**
     * 马赛克模式
     */
    private void choiceMosaicModel() {
        resetButtonState();
        if (mode == IMGMode.MOSAIC) {
            setIMGModeNone();
        } else {
            mode = IMGMode.MOSAIC;
            rb_mosaic.setPixelMap(ResourceTable.Media_image_ic_mosaic_checked);
            setIMGMode();
            showMosaicTip();
            disMissPaintColor();
            image.setCanTouch(true);
        }
    }

    /**
     * 裁剪模式
     */
    private void choiceCropModel() {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(getBundleName())
                .withAbilityName(ImageCropAbility.class.getName())
                .build();
        intent.setOperation(operation);
        intent.setParam("uri", Uri.parse(imgUri));
        GlobalData.getInstance().setCropperPixelMap(image.getCurrentBitmap());
        startAbilityForResult(intent, ImagePicker.REQUEST_CODE_CROP);  //单选需要裁剪，进入裁剪界面
    }

    /**
     * 还原文字编辑模式之前的状态
     */
    private void goPreState() {
        rg_modes.setVisibility(Component.VISIBLE);
        top_text.setText("");
        top_text.clearFocus();
        text_container.setVisibility(Component.INVISIBLE);
        disMissPaintColor();

        if (preMode == IMGMode.DOODLE) {
            rb_doodle.callOnClick();
        } else if (preMode == IMGMode.MOSAIC) {
            rb_mosaic.callOnClick();
        } else {
            mode = IMGMode.NONE;
        }
    }
}
